/*
 * Copyright (C) 2017 Intel Corporation.  All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#ifndef __MISC_H__
#define __MISC_H__
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#ifdef __cplusplus
extern "C" {
#endif

#ifndef MIN
#define MIN(a,b) (a)<(b)?(a):(b)
#endif

#define UNUSE(x) (void)(x)

// http://stackoverflow.com/questions/1640423/error-cast-from-void-to-int-loses-precision
#define PTR_TO_INT(arg)  (*((int*)(&arg)))

#define MACRO_STR(x) MICRO_DEF(x)
#define MICRO_DEF(x) #x

#define SECONDS_TO_DAYS(s) ((s)/(24*60*60))
#define SECONDS_TO_MINUTES(s) ((s)/(60))
#define SECONDS_TO_HOURS(s) ((s)/(60*60))
#define SECONDS_OF_DAY (24*60*60)

#ifndef _PLATFORM
#define SZ_PLATFORM "unknown"
#else
#define SZ_PLATFORM MACRO_STR(_PLATFORM)
#endif

#define COUNT_OF(x) (sizeof(x)/sizeof(x[0]))

#ifndef FIELD_OFFSET
#define FIELD_OFFSET(type, field)    ((long)(long*)&(((type *)0)->field))
#endif

#ifndef Add2Ptr
#define Add2Ptr(P,I) ((void*)((char*)(P) + (I)))
#endif

#ifndef ROUND_TO_SIZE
#define ROUND_TO_SIZE(_length, _alignment)    \
            (((_length) + ((_alignment)-1)) & ~((_alignment) - 1))
#endif

#ifndef FlagOn
#define FlagOn(_F,_SF)        ((_F) & (_SF))
#endif

#ifndef FlagOff
#define FlagOff(_F,_SF)        (((_F) & (_SF)) == 0)
#endif

#define SAFE_STRING2(_PTR, _DEFAULT) (_PTR?_PTR:_DEFAULT)
#define SAFE_STRING(_PTR) (_PTR?_PTR:"")


#define strdup2 make_string

void *malloc_z (size_t __size);


int delete_old_or_big_files(char * closed_dir, int days, unsigned long size_threshold);
unsigned long delete_folder_big_files(char * path, unsigned int bytes);

unsigned long get_file_size(const char *path , time_t * modi_time);
unsigned long dir_files_size(char * path);
void make_full_dir(char * path);
int create_socket_r();
int create_socket_random(int * port);
int wa_create_socket(int  port, int addressFamily);
int new_random_socket(bool is_udp, struct sockaddr * addr_out, socklen_t *socklen_inout);


bool wa_is_dir(char * path);

int already_running(const char *filename);
bool test_file_lock(const char *filename);

char * find_key_value(char * buffer, int buffer_len, const char * key, char * value, int value_len, char  delimiter);
 char * travel_key_value(char * buffer, int buffer_len,
        unsigned int *head,
        char * key_buf, int key_buf_len,
        int *value_len,
        char  delimiter);

int ini_get_int(const char* cfgname, char * key, int def);
const char * ini_get_str(const char* cfgname, const char * key, const char * def);

// value=NULL: unset the key from the file
bool set_ini_key(char *cfgname , const char * key, const char * value);

void prv_output_buffer(char * buffer,    int length);
int load_file_to_memory(const char *filename, char **result);
bool check_mount_path(char * path);
void do_copy(char *source, char *dest, char * args);
void do_install(const char *source, const char *dest, const char * mode, const char * owner, const char * group);
int rm_dir(char * path);
int save_content(char * filepath, char * content, int len);

int  float_to_str(double value, int decimals, char * str, int len);


char * get_string(char * data, int data_len, bool *allocated);
char * make_string(char * data, int data_len);

/*
        @brief          find a character from the source buffer and copy from the 
                        head to the found char (which is not included) to dest buffer.
        @return         size of bytes copied from the head to the found charachter
                        0  - not found
                        >0 - found
*/
#define SOURCE_LEN_STRING 0
int find_char_and_copy(char * source, int source_len, char c, char * dest, int dest_len);
void bh_output_buffer(FILE * stream, char * buffer, int length);

char * read_ini_key(const char * ini_path, const char * key, char * buf, int buf_len);


//
//  keys for /etc/ams/wasome.cfg
//
#define CONF_KEY_AMS_ROOT "AMS_ROOT"
#define CONF_KEY_WAPLC_ROOT "WAPLC_ROOT"
#define CONF_KEY_LOGGING_DIR "LOGGING_DIR"
char * read_global_setting(const char * key, char * buf, int buf_len);


#ifdef __cplusplus
}
#endif

#endif // __MISC_H_
